'use strict'; const { Document } = require('/document.js'); const { DocumentCommand, AddChildNodesCommandBuilder, NodeChildType } = require('/commands.js'); const { Dialog, DialogResult, UnitType } = require('/dialog.js'); const { CurveBuilder, PolyCurve } = require('/geometry.js'); const { PolyCurveNodeDefinition } = require('/nodes.js'); const { FillDescriptor } = require('/fills.js'); const { RGBA8 } = require('/colours.js'); const { LineStyle, LineStyleDescriptor } = require('/linestyle.js'); function isOk(result) { return (result?.value ?? result) === DialogResult.Ok.value; } function randomVividColour() { const h = Math.random() * 360; const s = 0.7 + Math.random() * 0.3; const v = 0.7 + Math.random() * 0.3; const c = v * s, x = c * (1 - Math.abs((h / 60) % 2 - 1)), m = v - c; let r = 0, g = 0, b = 0; if (h < 60) { r = c; g = x; b = 0; } else if (h < 120) { r = x; g = c; b = 0; } else if (h < 180) { r = 0; g = c; b = x; } else if (h < 240) { r = 0; g = x; b = c; } else if (h < 300) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } return RGBA8(Math.round((r+m)*255), Math.round((g+m)*255), Math.round((b+m)*255)); } function buildRandomCurve(doc, spread, nodeCount, minStroke, maxStroke, useRandomColour, fixedR, fixedG, fixedB, previewRef) { if (previewRef.node) { try { previewRef.node.delete(); } catch(e) {} previewRef.node = null; } doc.executeCommand(DocumentCommand.createSetCurrentSpread(spread)); const ext = spread.getSpreadExtents(); const x0 = ext.x, y0 = ext.y, w = ext.width, h = ext.height; // Pick a random stroke width between min and max const strokeWeight = minStroke + Math.random() * (maxStroke - minStroke); // Pick random or fixed colour const colour = useRandomColour ? randomVividColour() : RGBA8(fixedR, fixedG, fixedB); // Build single curve with all nodeCount anchor points const builder = CurveBuilder.create(); builder.begin({ x: x0 + Math.random() * w, y: y0 + Math.random() * h }); for (let i = 1; i < nodeCount; i++) { builder.lineToXY(x0 + Math.random() * w, y0 + Math.random() * h); } const poly = PolyCurve.create(); poly.addCurve(builder.createCurve()); const nodeDef = PolyCurveNodeDefinition.create( poly, FillDescriptor.createNone(), FillDescriptor.createSolid(colour), LineStyleDescriptor.create(LineStyle.createDefaultWithWeight(strokeWeight)), FillDescriptor.createNone() ); const batch = AddChildNodesCommandBuilder.create(); batch.setInsertionTarget(spread); batch.addNode(nodeDef); const cmd = batch.createCommand(false, NodeChildType.Main); doc.executeCommand(cmd); const created = []; cmd.newNodes.forEach(n => created.push(n)); if (created.length > 0) previewRef.node = created[0]; console.log(`Single curve — ${nodeCount} nodes, stroke ${strokeWeight.toFixed(1)}px`); } // ---- MAIN ---- const doc = Document.current; if (!doc) { console.log('ERROR: No document open.'); } else { const spread = doc.currentSpread; const previewRef = { node: null }; const dlg = Dialog.create('Random Connected Curve'); const col = dlg.addColumn(); const g1 = col.addGroup(''); const nodeCtrl = g1.addUnitValueEditor('Number of nodes', UnitType.Number, UnitType.Number, 100, 2, 10000).setPrecision(0); //const g2 = col.addGroup('Min stroke width (px)'); const minStrokeCtrl = g1.addUnitValueEditor('Min stroke width (px)', UnitType.Number, UnitType.Number, 1, 0.1, 500).setPrecision(1); //const g3 = col.addGroup('Max stroke width (px)'); const maxStrokeCtrl = g1.addUnitValueEditor('Max stroke width (px)', UnitType.Number, UnitType.Number, 10, 0.1, 500).setPrecision(1); //const g4 = col.addGroup('Random stroke colour'); const randomColourCheck = g1.addCheckBox('Random stroke colour', true); //const g5 = col.addGroup('Stroke Red (0-255)'); const rCtrl = g1.addUnitValueEditor('Stroke Red (0-255)', UnitType.Number, UnitType.Number, 0, 0, 255).setPrecision(0); //const g6 = col.addGroup('Stroke Green (0-255)'); const gCtrl = g1.addUnitValueEditor('Stroke Green (0-255)', UnitType.Number, UnitType.Number, 0, 0, 255).setPrecision(0); //const g7 = col.addGroup('Stroke Blue (0-255)'); const bCtrl = g1.addUnitValueEditor('Stroke Blue (0-255)', UnitType.Number, UnitType.Number, 0, 0, 255).setPrecision(0); //const g8 = col.addGroup('Preview'); const previewBtn = g1.addButton('Preview'); previewBtn.onClickHandler = () => { buildRandomCurve(doc, spread, Math.max(2, Math.round(nodeCtrl.value)), Math.min(minStrokeCtrl.value, maxStrokeCtrl.value), Math.max(minStrokeCtrl.value, maxStrokeCtrl.value), randomColourCheck.value, Math.round(rCtrl.value), Math.round(gCtrl.value), Math.round(bCtrl.value), previewRef); }; dlg.initialWidth = 420; const result = dlg.runModal(); if (isOk(result)) { buildRandomCurve(doc, spread, Math.max(2, Math.round(nodeCtrl.value)), Math.min(minStrokeCtrl.value, maxStrokeCtrl.value), Math.max(minStrokeCtrl.value, maxStrokeCtrl.value), randomColourCheck.value, Math.round(rCtrl.value), Math.round(gCtrl.value), Math.round(bCtrl.value), previewRef); } else { if (previewRef.node) { try { previewRef.node.delete(); } catch(e) {} } } }